package org.xmlibrary.util;

import java.io.OutputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;

/**
 * Implements an output stream consisting of joined <tt>ByteArrayOutpuStream</tt>s to avoid array capacity limits
 * 
 * @author a0u
 * @version 1.0 09-12-2008
 */
public class LongArrayOutputStream extends OutputStream
{
    private ArrayList<ByteArrayOutputStream> buffers;
    private long count;

    public LongArrayOutputStream()
    {
        super();
        buffers = new ArrayList<ByteArrayOutputStream>(5);
        reset();
    }

    private ByteArrayOutputStream newBuffer()
    {
        ByteArrayOutputStream buf = new ByteArrayOutputStream(1024);
        buffers.add(buf);
        return buf;
    }
    
    private ByteArrayOutputStream getCurrentBuffer()
    {
        return buffers.get(buffers.size() - 1);
    }
    
    public void write(byte[] b, int off, int len)
    {
        ByteArrayOutputStream current;
        current = getCurrentBuffer();
        if((long)current.size() + len > (long)Integer.MAX_VALUE)
            current = newBuffer();
        current.write(b, off, len);
        count += len;
    }
    
    public void write(int b)
    {
        ByteArrayOutputStream current;
        current = getCurrentBuffer();
        if((long)current.size() + 1 > (long)Integer.MAX_VALUE)
            current = newBuffer();
        current.write(b);
        count++;
    }
    
    public void writeTo(OutputStream out) throws IOException
    {
        for(ByteArrayOutputStream buf : buffers)
            out.write(buf.toByteArray(), 0, buf.size());
    }
    
    public long size()
    {
        return count;
    }
    
    public void reset()
    {
        buffers.clear();
        newBuffer();
        count = 0;
    }
        
}
